package com.demo;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * <p>
 * <code>PersonSelf</code>
 * </p>
 *
 * @author junbao3
 * TODO
 * @date 2023-06-07 9:04
 * Copyright (C) 2021 IFlyTek. All rights reserved.
 */
public class PersonSelf {
    private int i = 0;
    private static Unsafe unsafe;
    private static long i_offset;

    static {
        /*
            @CallerSensitive
            public static Unsafe getUnsafe() {
                Class var0 = Reflection.getCallerClass();
                if (var0.getClassLoader() != null) {
                    throw new SecurityException("Unsafe");
                } else {
                    return theUnsafe;
                }
            }
        */
        //直接这样用会抛出异常 因为person类的类加载器是app，不为null
//        unsafe = Unsafe.getUnsafe();
        //Unsafe类有一个属性Unsafe theUnsafe，可以通过反射获取
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
            i_offset = unsafe.objectFieldOffset(PersonSelf.class.getDeclaredField("i"));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws InterruptedException {
        final PersonSelf person = new PersonSelf();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50000; ) {
                    while (true) {
                        boolean b = unsafe.compareAndSwapInt(person, i_offset, person.i, person.i + 1);
                        if (b) {
                            i++;
                            break;
                        }
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50000; ) {
                    while (true) {
                        boolean b = unsafe.compareAndSwapInt(person, i_offset, person.i, person.i + 1);
                        if (b) {
                            i++;
                            break;
                        }
                    }
                }
            }
        }).start();

        Thread.sleep(1000);

        System.out.println(person.i);
    }
}
